package com.alks.function.service.impl.stockdept.pcfactorystockquery;

import com.alibaba.excel.util.StringUtils;
import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.dto.SysUserTokenDTO;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.utils.beanutils.ArrayUtils;
import com.alks.common.utils.beanutils.BeanUtil;
import com.alks.entity.data.entity.PcCuttingCollectDetail;
import com.alks.entity.data.entity.PcCuttingLsPart;
import com.alks.entity.data.entity.PcLotHead;
import com.alks.entity.data.enums.factoryquery.PcCuttingProcecssEnum;
import com.alks.entity.data.enums.stock.LsTypeEnum;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.InDataException;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.biocontrol.webwork.RecIoBatchRequest;
import com.alks.function.data.dto.stockdept.pcfactoryquery.PartName;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.CutScanCodeDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.CutScanLotDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.CuttingRecDetDto;
import com.alks.function.data.dto.stockdept.pcfactorystockwork.CuttingRecTempDto;
import com.alks.function.data.request.factoryquery.CuttingPartRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.CuttingRceIoBackRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.CuttingRecDetRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.CuttingRecIoRequest;
import com.alks.function.data.request.stockdept.pcfactorystockwork.CuttingRecTempRequest;
import com.alks.function.data.vo.controller.stockdept.DeptProcNumVo;
import com.alks.function.mapper.SdDepartmentMapper;
import com.alks.function.mapper.chengKong.PcLotHeadMapper;
import com.alks.function.mapper.pcfactoryquery.FT_QR_PcCuttingLsPartMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.PcCuttingCollectDetailMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.PcCuttingLsLabelMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.PcLotPartProcessMapper;
import com.alks.function.service.stockdept.pcfactorystockquery.ICuttingRecService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import jodd.util.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.alks.entity.data.enums.factoryquery.PcProcessEnum.PROCESS_CUT;
import static com.alks.entity.data.enums.stock.LsTypeEnum.*;

/**
 * @author MS
 * @since 2024/6/28下午5:05
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class CuttingRecServiceImpl extends ServiceImpl<PcCuttingCollectDetailMapper, PcCuttingCollectDetail> implements ICuttingRecService {
    private final PcCuttingCollectDetailMapper detailMapper;
    private final FT_QR_PcCuttingLsPartMapper partMapper;
    private final PcLotHeadMapper lotHeadMapper;
    private final PcCuttingLsLabelMapper labelMapper;
    private final PcLotPartProcessMapper processMapper;
    private final SdDepartmentMapper deptMapper;

    private final String CutCode = "01";
    private final String ProcCode = "02";
    private final String KitCode = "03";

    @Override
    @AutoPageAop
    public ResponseInfo cuttingRecTempQuery(CuttingRecTempRequest request, String processCode) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取数据*/
        List<CuttingRecTempDto> dtos = partMapper.cuttingRecTempQuery(request, processCode, companyId);
        Page<CuttingRecTempDto> page = (Page<CuttingRecTempDto>) dtos;
        /*封装返回*/
        Map<String, Object> map = new HashMap<>(2);
        map.put("dtos", dtos);
        map.put("total", page.getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    @AutoPageAop
    public ResponseInfo cuttingRecDetQuery(CuttingRecDetRequest request, String processCode) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取数据*/
        request.setLsCollectType(LsTypeEnum.getTypeCode(request.getLsCollectType()));
        List<PcCuttingCollectDetail> details = lambdaQuery()
                .eq(PcCuttingCollectDetail::getLotNo, request.getLotNo())
                .eq(PcCuttingCollectDetail::getProcessCode, processCode)
                .like(StringUtil.isNotBlank(request.getLsCollectType()), PcCuttingCollectDetail::getLsCollectType, request.getLsCollectType())
                .like(StringUtil.isNotBlank(request.getPartName()), PcCuttingCollectDetail::getPartName, request.getPartName())
                .like(StringUtil.isNotBlank(request.getSizeNo()), PcCuttingCollectDetail::getSizeNo, request.getSizeNo())
                .eq(PcCuttingCollectDetail::getCompanyId, companyId).list();
        Page<PcCuttingCollectDetail> page = (Page<PcCuttingCollectDetail>) details;
        List<CuttingRecDetDto> dtos = BeanUtil.copyList(details, CuttingRecDetDto.class);
        /*处理收发类型*/
        for (CuttingRecDetDto dto : dtos) {
            dto.setLsCollectType(LsTypeEnum.getTypeName(dto.getLsCollectType()));
            dto.setPartName1(dto.getPartName());
        }
        /*封装返回*/
        Map<String, Object> map = new HashMap<>(2);
        map.put("dtos", dtos);
        map.put("total", page.getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo cuttingInDateQuery(LocalDateTime dateInfo, String processCode) {
        String companyId = UserIdThread.get().getCompanyId();
        /*封装返回各当日总览数据*/
        Map<String, Integer> map = detailMapper.selectCollectLotNum(companyId, dateInfo, processCode);
        map.put("inPartNum", detailMapper.countCollectPartNum(companyId, dateInfo, processCode));
        map.put("inMatchNum", detailMapper.countMatchNum(companyId, dateInfo, processCode));
        map.putAll(detailMapper.selectCollectOutLotNum(companyId, dateInfo, processCode));
        map.put("outPartNum", detailMapper.countCollectOutPartNum(companyId, dateInfo, processCode));
        map.put("outMatchNum", detailMapper.countOutMatchNum(companyId, dateInfo, processCode));
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo cuttingRecDetBack() {
        return ResponseInfo.ok(LsTypeEnum.getAllTypeNames());
    }

    @Override
    @AutoPageAop
    public ResponseInfo cuttingRecIoTempBack(CuttingRceIoBackRequest request, String processCode) {
        String companyId = UserIdThread.get().getCompanyId();
        /*入参判断*/
        if (request.getType() != null && !request.getType().equals(1) && !request.getType().equals(0)) {
            log.warn("\n异常接口：cuttingRecIoTempBack\n异常原因：传参数据错误\n需求参数：0-出库 1-入库\n实际参数：{}", request.getType());
            throw new InDataException("出入库类型传参异常");
        }
        /*获取部位数据*/
        List<CuttingRecDetDto> dtos = partMapper.cuttingRecIoTempBack(request, processCode, companyId);
        Page<CuttingRecDetDto> page = (Page<CuttingRecDetDto>) dtos;
        if (ArrayUtils.isEmpyt(dtos)) {
            dtos = new ArrayList<>();
        }
        Map<String, Object> map = new HashMap<>(2);
        map.put("dtos", dtos);
        map.put("total", page.getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo cuttingRecIoBack(CuttingRceIoBackRequest request, String processCode) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取部位数据*/
        LambdaQueryWrapper<PcCuttingLsPart> partWrapper = new LambdaQueryWrapper<PcCuttingLsPart>()
                .select(PcCuttingLsPart::getPartName)
                .eq(PcCuttingLsPart::getLotNo, request.getLotNo())
                .eq(PcCuttingLsPart::getProcessCode, processCode)
                .apply(request.getType().equals(1), "IFNULL(LS_QTY,0) > IFNULL(PROD_QTY,0)")
                .apply(request.getType().equals(0), "IFNULL(PROD_QTY,0) > IFNULL(SEND_QTY,0)")
                .in(ArrayUtils.isNoEmpyt(request.getLsNos()), PcCuttingLsPart::getLsNo, request.getLsNos())
                .in(ArrayUtils.isNoEmpyt(request.getSizeNos()), PcCuttingLsPart::getSizeNo, request.getSizeNos())
                .eq(PcCuttingLsPart::getCompanyId, companyId)
                .last("GROUP BY PART_NAME");
        List<PartName> partName1 = partMapper.selectList(partWrapper)
                .stream().map(a->new PartName().setPartName1(a.getPartName())).collect(Collectors.toList());
        List<String> partName = partMapper.selectList(partWrapper)
                .stream().map(PcCuttingLsPart::getPartName).collect(Collectors.toList());
        /*获取轮次*/
        LambdaQueryWrapper<PcCuttingLsPart> lsWrapper = new LambdaQueryWrapper<PcCuttingLsPart>()
                .select(PcCuttingLsPart::getLsNo)
                .eq(PcCuttingLsPart::getLotNo, request.getLotNo())
                .eq(PcCuttingLsPart::getProcessCode, processCode)
                .apply(request.getType().equals(1), "IFNULL(LS_QTY,0) > IFNULL(PROD_QTY,0)")
                .apply(request.getType().equals(0), "IFNULL(PROD_QTY,0) > IFNULL(SEND_QTY,0)")
                .in(ArrayUtils.isNoEmpyt(request.getPartNames()), PcCuttingLsPart::getPartName, request.getPartNames())
                .in(ArrayUtils.isNoEmpyt(request.getSizeNos()), PcCuttingLsPart::getSizeNo, request.getSizeNos())
                .eq(PcCuttingLsPart::getCompanyId, companyId)
                .last("GROUP BY LS_NO");
        List<BigDecimal> lsNo = partMapper.selectList(lsWrapper)
                .stream().map(PcCuttingLsPart::getLsNo).collect(Collectors.toList());
        /*获取号码*/
        LambdaQueryWrapper<PcCuttingLsPart> sizeWrapper = new LambdaQueryWrapper<PcCuttingLsPart>()
                .select(PcCuttingLsPart::getSizeNo)
                .eq(PcCuttingLsPart::getLotNo, request.getLotNo())
                .eq(PcCuttingLsPart::getProcessCode, processCode)
                .apply(request.getType().equals(1), "IFNULL(LS_QTY,0) > IFNULL(PROD_QTY,0)")
                .apply(request.getType().equals(0), "IFNULL(PROD_QTY,0) > IFNULL(SEND_QTY,0)")
                .in(ArrayUtils.isNoEmpyt(request.getPartNames()), PcCuttingLsPart::getPartName, request.getPartNames())
                .in(ArrayUtils.isNoEmpyt(request.getLsNos()), PcCuttingLsPart::getLsNo, request.getLsNos())
                .eq(PcCuttingLsPart::getCompanyId, companyId)
                .last("GROUP BY SIZE_NO");
        List<String> sizeNo = partMapper.selectList(sizeWrapper)
                .stream().map(PcCuttingLsPart::getSizeNo).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>(3);
        map.put("partName1", partName1);
        map.put("partName", partName);
        map.put("lsNo", lsNo);
        map.put("sizeNo", sizeNo);
        return ResponseInfo.ok(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseInfo cuttingRecDetIo(List<CuttingRecIoRequest> request, String processCode, String language) {
        /*判断入参完整性*/
        String webName = "web";
        String deptName;
        String deptNo;
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        String userName = tokenDTO.getUserName();
        String collectPad = request.get(0).getCollectPad();
        LocalDateTime now = LocalDate.now().atStartOfDay();
        /*操作方式必须唯一*/
        Set<String> collectSet = request.stream().map(CuttingRecIoRequest::getCollectPad).collect(Collectors.toSet());
        if (collectSet.size() != 1) {
            throw new InDataException(getMessage("操作方式必须唯一", "Kiểu vận hành phải duy nhất", language));
        }
        if (webName.equals(collectPad)) {
            /*如果是web则在token获取部门数据*/
            deptNo = tokenDTO.getDeptId();
            if (deptNo == null) {
                log.warn("\n异常接口：cuttingRecDetIo\n异常原因：员工{}未查询到所属部门信息", userName);
                throw new ServiceErrorException(getMessage("员工信息异常", "Thông tin nhân viên bất thường", language));
            }
            deptName = deptMapper.getOne(deptNo).getDeptName();
        } else {
            deptNo = null;
            deptName = request.get(0).getDeptName();
            /*标签判断*/
//            List<CuttingRecIoRequest> batchEmpty = request.stream()
//                    .filter(a -> ArrayUtils.isEmpyt(a.getBatchNoList()))
//                    .collect(Collectors.toList());
//            if (ArrayUtils.isNoEmpyt(batchEmpty)){
//                String msg = "第 " + batchEmpty.get(0).getLsNo() + " 轮的 " + batchEmpty.get(0).getPartName() + "(" + batchEmpty.get(0).getSizeNo() + ") ";
//                log.warn("\n异常接口：cuttingRecDetIo\n异常原因:标签未生成\n参数：{}",batchEmpty.get(0));
//                throw new InDataException(msg+"标签未生成");
//            }
        }
        /*type必须有且唯一*/
        Set<String> typeSet = request.stream()
                .map(CuttingRecIoRequest::getType)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        if (typeSet.size() != 1) {
            log.error("\n错误接口：cuttingRecDetIo\n错误原因：传入TYPE种类不为一：{}", typeSet.size());
            throw new InDataException(getMessage("操作异常", "Thao tác bất thường", language));
        }
        if (!typeSet.contains(SEND_OUT.getTypeCode()) && !typeSet.contains(SM_IN.getTypeCode()) && !typeSet.contains(SG_IN.getTypeCode())) {
            log.error("\n错误接口：cuttingRecDetIo\n错误原因：传入TYPE不在可选范围内：{}", typeSet);
            throw new InDataException(getMessage("操作异常", "Thao tác bất thường", language));
        }
        /*指令必须唯一*/
        Set<String> lotNoSet = request.stream().map(CuttingRecIoRequest::getLotNo).collect(Collectors.toSet());
        if (lotNoSet.size() != 1) {
            throw new InDataException(getMessage("无法同时对不同指令下数据进行收发", "Không thể đồng thời thu phát dữ liệu dưới các chỉ lệnh khác nhau", language));
        }
        /*判断指令是否存在*/
        LambdaQueryWrapper<PcLotHead> lotWrapper = new LambdaQueryWrapper<PcLotHead>()
                .select(PcLotHead::getLotNo, PcLotHead::getStyle)
                .eq(PcLotHead::getLotNo, request.get(0).getLotNo())
                .eq(PcLotHead::getCompanyId, companyId)
                .last("LIMIT 1");
        PcLotHead lotHead = lotHeadMapper.selectOne(lotWrapper);
        if (lotHead == null) {
            throw new ServiceErrorException(getMessage("指令不存在", "Chỉ lệnh không tồn tại", language));
        }
        /*获取标签数据*/
        List<PcCuttingCollectDetail> detailList = labelMapper.cuttingRecDetIo(request, companyId,processCode);
        if (ArrayUtils.isEmpyt(detailList)) {
            throw new ServiceErrorException(getMessage("标签未生成", "Nhãn chưa được tạo", language));
        }
        /*找出未生成标签的数据抛出异常*/
        Set<String> findSet = detailList.stream().map(r -> "第 " + r.getLsNo().intValue() + " 轮的 " + r.getPartName() + "(" + r.getSizeNo() + ") ").collect(Collectors.toSet());
        Set<String> requestSet = request.stream().map(r -> "第 " + r.getLsNo().intValue() + " 轮的 " + r.getPartName() + "(" + r.getSizeNo() + ") ").collect(Collectors.toSet());
        List<String> miss = ArrayUtils.findMiss(requestSet, findSet);
        if (ArrayUtils.isNoEmpyt(miss)) {
            String errorMsg = miss.get(0) + getMessage("标签未生成", "Nhãn chưa được tạo", language);
            return ResponseInfo.error(errorMsg);
        }
        /*检测出入库是否符合规范*/
        ioCheck(processCode, detailList, companyId, language);
        for (PcCuttingCollectDetail detail : detailList) {
            /*补全数据*/
            detail.setProcessCode(processCode);
            detail.setCollectTime(now);
            detail.setCollectUser(userName);
            detail.setCollectPad(collectPad);
            detail.setLotNo(lotHead.getLotNo());
            detail.setProcessCode(processCode);
            detail.setProdTime(now);
            detail.setStyle(lotHead.getStyle());
            detail.setDeptName(deptName);
            detail.setDeptNo(deptNo);
            /*写入数据*/
            try {
                detailMapper.insert(detail);
            } catch (DuplicateKeyException e) {
                throw new ServiceErrorException(getMessage("请勿重复收料", "Vui lòng không thu liệu trùng lặp", language));
            }
        }
        return ResponseInfo.ok();
    }

    // 添加辅助方法用于获取不同语言的消息
    private String getMessage(String chinese, String vietnamese, String language) {
        if ("vi".equals(language)) {
            return vietnamese;
        }
        return chinese;
    }

    /**
     * 收料校验
     *
     * @param processCode 工艺ID
     * @param request     收料数据
     * @param companyId   公司ID
     * @param language    语言
     */
    private void ioCheck(String processCode, List<PcCuttingCollectDetail> request, String companyId, String language) {
        /*判断工艺是否存在*/
        for (PcCuttingCollectDetail detail : request) {
            Integer count = partMapper.findProcess(processCode, detail, companyId);
            if (count != 1) {
                throw new ServiceErrorException(getMessage("该单不存在此工序", "Đơn này không tồn tại công đoạn này", language));
            }
        }
        /*判断是否已入库*/
        if (!SEND_OUT.getTypeCode().equals(request.get(0).getLsCollectType())) {
            List<String> labelList = request.stream().map(PcCuttingCollectDetail::getLabelNo).collect(Collectors.toList());
            LambdaQueryWrapper<PcCuttingCollectDetail> wrapper = new LambdaQueryWrapper<PcCuttingCollectDetail>()
                    .eq(PcCuttingCollectDetail::getCompanyId, companyId)
                    .eq(PcCuttingCollectDetail::getProcessCode, processCode)
                    .in(PcCuttingCollectDetail::getLabelNo, labelList);
            List<PcCuttingCollectDetail> detailList = detailMapper.selectList(wrapper);
            if (ArrayUtils.isNoEmpyt(detailList)) {
                throw new ServiceErrorException(getMessage("存在重复收料", "Tồn tại thu liệu trùng lặp", language));
            }
        }
        if (!PROCESS_CUT.getProcessCode().equals(processCode) || SEND_OUT.getTypeCode().equals(request.get(0).getLsCollectType())) {
            /*判断前置工艺是否完成*/
            if (SEND_OUT.getTypeCode().equals(request.get(0).getLsCollectType())) {
                /*发料工艺判断*/
                for (PcCuttingCollectDetail detail : request) {
                    Integer count = partMapper.sendUnFinPrecode(processCode, detail.getLabelNo(), companyId);
                    if (count != 1) {
                        log.error("\n错误接口：ioCheck\n错误原因：此标签未发料\n异常数据：标签：{},工艺:{},该标签发货数量：{}",
                                detail.getLabelNo(), processCode, count);
                        throw new ServiceErrorException(getMessage("此标签未收料", "Nhãn này chưa được thu liệu", language));
                    }
                }
            } else {
                /*收料工艺判断*/
                for (PcCuttingCollectDetail detail : request) {
                    /*获取此前最大工艺号*/
                    String lastProcessCode = partMapper.getLastProcessCode(processCode, detail, companyId);
                    if (StringUtils.isBlank(lastProcessCode)) {
                        /*无前置工艺跳过*/
                        return;
                    }
                    /*判断最近工艺是否发料*/
                    Integer count = partMapper.recUnFinPrecode(lastProcessCode, detail.getLabelNo(), companyId);
                    if (count != 1) {
                        log.error("\n错误接口：ioCheck\n错误原因：前置工艺发料不足\n异常数据：标签：{},前置工艺:{},该标签发货数量：{}",
                                detail.getLabelNo(), lastProcessCode, count);
                        throw new ServiceErrorException(getMessage("前置工艺未完成", "Công đoạn trước chưa hoàn thành", language));
                    }
                }
            }
        }
        /*判断是否超出收货数量限制*/
        PcCuttingLsPart remainPart = partMapper.remainQtyAfterIo(processCode, request, companyId);
        if (remainPart != null) {
            throw new ServiceErrorException(getMessage("超出可收发数量", "Vượt quá số lượng có thể thu phát", language));
        }
    }

    @Override
    public ResponseInfo cuttingRecDetDelete(PcCuttingCollectDetail request, String processCode) {
        SysUserTokenDTO tokenDTO = UserIdThread.get();
        String companyId = tokenDTO.getCompanyId();
        /*判断数据存在*/
        request.setLsCollectType(LsTypeEnum.getTypeCode(request.getLsCollectType()));
        Integer detailCount = lambdaQuery()
                .eq(PcCuttingCollectDetail::getLotNo, request.getLotNo())
                .eq(PcCuttingCollectDetail::getLsCollectType, request.getLsCollectType())
                .eq(PcCuttingCollectDetail::getProcessCode, processCode)
                .eq(PcCuttingCollectDetail::getLsNo, request.getLsNo())
                .eq(PcCuttingCollectDetail::getSizeNo, request.getSizeNo())
                .eq(PcCuttingCollectDetail::getPartName, request.getPartName())
                .eq(PcCuttingCollectDetail::getCollectTime, request.getCollectTime())
                .eq(PcCuttingCollectDetail::getCollectPad, request.getCollectPad())
                .eq(StringUtils.isNotBlank(request.getLabelNo()), PcCuttingCollectDetail::getLabelNo, request.getLabelNo())
                .isNull(StringUtils.isBlank(request.getLabelNo()), PcCuttingCollectDetail::getLabelNo)
                .eq(PcCuttingCollectDetail::getCompanyId, companyId)
                .eq(PcCuttingCollectDetail::getInQty, request.getInQty()).count();
        if (detailCount == 0) {
            return ResponseInfo.error("无效记录");
        }
        /*如果不是发料且存在发料记录则不能删除*/
        if (!SEND_OUT.getTypeCode().equals(request.getLsCollectType())) {
            Integer count = lambdaQuery()
                    .eq(PcCuttingCollectDetail::getLotNo, request.getLotNo())
                    .eq(PcCuttingCollectDetail::getLsCollectType, SEND_OUT.getTypeCode())
                    .eq(PcCuttingCollectDetail::getProcessCode, processCode)
                    .eq(PcCuttingCollectDetail::getLsNo, request.getLsNo())
                    .eq(PcCuttingCollectDetail::getSizeNo, request.getSizeNo())
                    .eq(PcCuttingCollectDetail::getPartName, request.getPartName())
                    .eq(PcCuttingCollectDetail::getCollectTime, request.getCollectTime())
                    .eq(PcCuttingCollectDetail::getCollectPad, request.getCollectPad())
                    .eq(StringUtils.isNotBlank(request.getLabelNo()), PcCuttingCollectDetail::getLabelNo, request.getLabelNo())
                    .isNull(StringUtils.isBlank(request.getLabelNo()), PcCuttingCollectDetail::getLabelNo)
                    .eq(PcCuttingCollectDetail::getCompanyId, companyId)
                    .eq(PcCuttingCollectDetail::getInQty, request.getInQty()).count();
            if (count > 0) {
                return ResponseInfo.error("存在发料记录，不能删除");
            }
        }
        if (StringUtil.isNotBlank(request.getLabelNo())) {
            detailMapper.deleteByLabel(request.getLabelNo(), processCode, companyId, request.getLsCollectType());
        } else {
            /*删除数据*/
            LambdaQueryWrapper<PcCuttingCollectDetail> wrapper = new LambdaQueryWrapper<PcCuttingCollectDetail>()
                    .eq(PcCuttingCollectDetail::getLotNo, request.getLotNo())
                    .eq(PcCuttingCollectDetail::getLsCollectType, request.getLsCollectType())
                    .eq(PcCuttingCollectDetail::getProcessCode, processCode)
                    .eq(PcCuttingCollectDetail::getLsNo, request.getLsNo())
                    .eq(PcCuttingCollectDetail::getSizeNo, request.getSizeNo())
                    .eq(PcCuttingCollectDetail::getPartName, request.getPartName())
                    .eq(PcCuttingCollectDetail::getCollectTime, request.getCollectTime())
                    .eq(PcCuttingCollectDetail::getCollectPad, request.getCollectPad())
                    .eq(PcCuttingCollectDetail::getCompanyId, companyId)
                    .eq(PcCuttingCollectDetail::getInQty, request.getInQty())
                    .last("LIMIT 1");
            detailMapper.delete(wrapper);
        }
        /*创建返回值*/
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo cuttingScanCodeQuery(String labelNo, String processName, String flag, String language) {
        String companyId = UserIdThread.get().getCompanyId();
        /*处理工艺数据*/
        String processNo = PcCuttingProcecssEnum.getCodeByName(processName);
        /*获取数据*/
        CutScanCodeDto dto = labelMapper.cuttingScanCodeQuery(labelNo, processNo, flag, companyId);
        if (dto == null) {
            return ResponseInfo.error(getMessage("标签不存在", "Nhãn không tồn tại", language));
        }
        return ResponseInfo.ok(dto);
    }

    @Override
    public ResponseInfo cuttingScanLotNoQuery(CuttingPartRequest request, String language) {
        String companyId = UserIdThread.get().getCompanyId();
        /*处理工艺数据*/
        String processNo = PcCuttingProcecssEnum.getCodeByName(request.getProcessCode());
        /*获取数据*/
        List<CutScanLotDto> scanCode = partMapper.cuttingScanCodeQuery(request, processNo, companyId);
        if (scanCode == null) {
            return ResponseInfo.error(getMessage("数据不存在", "Dữ liệu không tồn tại", language));
        }
        /*处理数据结构*/
        Map<String, List<CutScanLotDto>> dtos = scanCode.stream().collect(Collectors.groupingBy(CutScanLotDto::getPartName));
        return ResponseInfo.ok(dtos);
    }

    @Override
    public List<DeptProcNumVo> getProdNumByDate(LocalDateTime start, LocalDateTime end) {
        String companyId = UserIdThread.get().getCompanyId();
        /*初始化日期*/
        start = start == null ? LocalDate.now().atStartOfDay() : start;
        end = end == null ? LocalDateTime.now() : end;
        /*获取数据*/
        List<DeptProcNumVo> voList = detailMapper.getProdNumByDate(start, end, companyId);
        return voList;
    }

    @Override
    public List<Map<String, Object>> batchQuery(RecIoBatchRequest request, String processCode) {
        String companyId = UserIdThread.get().getCompanyId();
        /*获取可收发批次*/
        return null;
    }
}
